package org.osgroup.service;

import org.osgroup.dto.HeartbeatResponse;
import org.osgroup.monitor.HeartbeatMonitor;
import org.osgroup.project.BaseProject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import jakarta.annotation.PostConstruct;
import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 心跳监控服务
 */
@Service
public class HeartbeatService {
    
    @Autowired
    private FoodStreetService foodStreetService;
    
    @Autowired
    private RollerCoasterService rollerCoasterService;
    
    private HeartbeatMonitor monitor;
    
    @PostConstruct
    public void init() {
        // 创建监控器
        monitor = HeartbeatMonitor.getInstance(5);
        
        // 注册美食街到监控器
        monitor.registerProject(foodStreetService.getFoodStreet());
        
        // 注册激流勇进到监控器
        monitor.registerProject(rollerCoasterService.getRollerCoaster());
        
        // 启动美食街自动心跳
        foodStreetService.getFoodStreet().startAutoHeartbeat();
        
        // 启动激流勇进自动心跳
        rollerCoasterService.getRollerCoaster().startAutoHeartbeat();
        
        // 启动监控
        monitor.startMonitoring();
        
        System.out.println("✅ 心跳监控服务已初始化 - 已注册项目: 美食街, 激流勇进");
    }
    
    public HeartbeatResponse getHeartbeatStatus() {
        HeartbeatResponse response = new HeartbeatResponse();
        Map<String, HeartbeatResponse.ProjectStatus> projectsMap = new HashMap<>();
        
        if (monitor != null) {
            List<BaseProject> projects = monitor.getMonitoredProjects();
            
            for (BaseProject project : projects) {
                HeartbeatResponse.ProjectStatus status = new HeartbeatResponse.ProjectStatus();
                status.setStatus(project.isAlive() ? "normal" : "timeout");
                status.setLastHeartbeat(formatTimestamp(project.getLastHeartbeatTime()));
                
                // 使用项目名称映射到前端期望的键名
                String projectId = mapProjectNameToKey(project.getProjectName());
                projectsMap.put(projectId, status);
            }
        }
        
        response.setProjects(projectsMap);
        return response;
    }
    
    /**
     * 将中文项目名称映射到前端期望的英文键名
     */
    private String mapProjectNameToKey(String projectName) {
        if (projectName == null) {
            return "unknown";
        }
        
        switch (projectName) {
            case "美食街":
                return "foodStreet";
            case "激流勇进":
                return "rollerCoaster";
            case "VR影院":
                return "vrCinema";
            case "休息区":
                return "restArea";
            case "摆渡车":
                return "shuttle";
            case "出入口":
                return "entranceExit";
            default:
                // 如果是英文名称,尝试使用toJsonKey转换
                return toJsonKey(projectName);
        }
    }
    
    /**
     * 将项目名称转换为JSON键名(驼峰命名)
     */
    private String toJsonKey(String projectName) {
        if (projectName == null || projectName.isEmpty()) {
            return "unknown";
        }
        
        StringBuilder result = new StringBuilder();
        boolean capitalizeNext = false;
        
        for (char c : projectName.toCharArray()) {
            if (Character.isLetterOrDigit(c)) {
                if (capitalizeNext) {
                    result.append(Character.toUpperCase(c));
                    capitalizeNext = false;
                } else {
                    result.append(Character.toLowerCase(c));
                }
            } else {
                capitalizeNext = true;
            }
        }
        
        return result.length() > 0 ? result.toString() : "unknown";
    }
    
    /**
     * 格式化时间戳为ISO 8601格式
     */
    private String formatTimestamp(long timestamp) {
        LocalDateTime dateTime = LocalDateTime.ofInstant(
            Instant.ofEpochMilli(timestamp),
            ZoneId.of("UTC")
        );
        return dateTime.format(DateTimeFormatter.ISO_LOCAL_DATE_TIME) + "Z";
    }
}
